<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
</head>
<body>
    <script>
        function fn(name,age) {
            this.name = name
            this.age = age

            return 1
        }

        fn.prototype.eat = function (){
            console.log("吃遍天南海北");
        }

        // console.log(new fn("张三","18"));//打印的是这个实例
        // console.log(fn("张三","18"));//undefined

        //不确定有几个参数是,用剩余参数进行接收
        function myNew(constr,...args) {
            //创建一个对象
            const obj = {}
            //让fn的this指向这个对象
            // fn.call(obj)
            // apply做了三件事:改变函数的this指向,调用前面的函数,接收前面函数的返回值
            const result = constr.apply(obj,args)
            //让obj的隐式原型指向fn的显示原型对象,
            //如果直接把fn的显示原型赋给obj
            obj.__proto__ = constr.prototype
            //判断fn的返回值,当fn返回的是引用数据类型时,new表达式直接返回这个引用数据,否则返回实例对象本身
            if(typeof result === "object" && typeof result !== "null" || typeof result === "function"){
                return result
            }else{
                return obj
            }
        }

        // console.log(myNew(fn,"李四",21))
        const p1 = myNew(fn,"李四",21)
        p1.eat()
        console.log(p1)

    </script>
</body>
</html>